﻿using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using SnippetBox.Core.Common.Paging;
using SnippetBox.Core.Data.Models;

namespace SnippetBox.Core.Data.Service {
    public class SnippetService : ServiceBase<Snippet>{
        private const int PAGE_SIZE = 10;

        public IPagedList<Snippet> GetAllPaged(int? page) {
            return _repository.GetAll().OrderByDescending(x => x.DateCreated).ToPagedList(page, PAGE_SIZE);
        }

        public List<Snippet> GetAllWithCategory() {
            return _repository.GetAll().Include("Category").Include("Author").ToList();
        }

        public List<Snippet> GetLatestSnippets(int count) {
            return _repository
                .GetAll()
                .OrderByDescending(s => s.DateCreated)
                .Take(count)
                .ToList();
        }

        public List<Snippet> GetPopularSnippets(int count) {
            return _repository
                .GetAll()
                .OrderByDescending(s => s.Views + (s.Favorited * 3))
                .Take(count)
                .ToList();
        }

        public IPagedList<Snippet> Search(string query, int? page) {
            return _repository
                .Where(x => x.Title.Contains(query) || x.BodyRaw.Contains(query))
                .OrderByDescending(x => x.DateCreated)
                .ToPagedList(page, PAGE_SIZE);
        }

        public IPagedList<Snippet> GetAllPagedByUser(int? page, User user) {
            return _repository
                .Where(x => x.Author.UserId == user.UserId)
                .OrderByDescending(x => x.DateCreated)
                .ToPagedList(page, PAGE_SIZE);
        }

        public IPagedList<Snippet> SearchFromUser(string query, int? page, User user) {
            return _repository
                .Where(x => x.Author.UserId == user.UserId && (x.Title.Contains(query) || x.BodyRaw.Contains(query)))
                .OrderByDescending(x => x.DateCreated)
                .ToPagedList(page, PAGE_SIZE);
        }

        public IPagedList<Snippet> GetByCategory(int categoryId, int? page) {
            return _repository
                .Where(x => x.Category.CategoryId == categoryId)
                .OrderBy(x => x.DateCreated)
                .ToPagedList(page, PAGE_SIZE);
        }

        public Snippet GetByIdForDetails(int snippetId) {
            return _repository.Where(x => x.SnippetId == snippetId)
                .Include(x => x.UsersFavorited)
                .SingleOrDefault();
        }

        public IPagedList<Snippet> GetPagedFavoritesByUser(int? page, User user) {
            return _repository
                .Where(x => x.UsersFavorited.Any(u => u.UserId == user.UserId))
                .OrderByDescending(x => x.DateCreated)
                .ToPagedList(page, PAGE_SIZE);
        }
    }
}
